﻿using Modbus.Device;
using Sunny.UI;
using Sunny.UI.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Org.BouncyCastle.Math.EC.ECCurve;
using static PressureTest.Log;
namespace PressureTest
{
    public partial class Index : Form
    {
        /// <summary>串口字典
        ///  串口地址为Key
        /// </summary>
        private Dictionary<string, SerialPort> serialPortDic = new Dictionary<string, SerialPort> { };

        /// <summary>串口字典
        /// 设备编号为Key
        /// </summary>
        private Dictionary<string, SerialPort> deviceSerialPortDic = new Dictionary<string, SerialPort> { };

        /// <summary>点位字典
        /// 
        /// </summary>
        private Dictionary<string, Dictionary<string, object>> masterDic = new Dictionary<string, Dictionary<string, object>> { };

        /// <summary>界面点位字典
        /// 
        /// </summary>
        private Dictionary<string, string> frormPointDic = new Dictionary<string, string> { };

        /// <summary>语音串口
        /// 
        /// </summary>
        private SerialPort voiceSerialPort;

        /// <summary>语音设备地址
        /// 
        /// </summary>
        private string voiceDeviceAddress;

        /// <summary>语音播报状态
        /// 
        /// </summary>
        private bool voiceBroadcastState = false;

        /// <summary>窗口禁止调整大小
        /// 
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == 0x112)
            {
                switch ((int)m.WParam)
                {
                    //禁止双击标题栏关闭窗体
                    case 0xF063:
                    case 0xF093:
                        m.WParam = IntPtr.Zero;
                        break;

                    //禁止拖拽标题栏还原窗体
                    case 0xF012:
                    case 0xF010:
                        m.WParam = IntPtr.Zero;
                        break;

                    //禁止双击标题栏
                    case 0xf122:
                        m.WParam = IntPtr.Zero;
                        break;

                    //允许关闭按钮
                    case 0xF060:
                        //m.WParam = IntPtr.Zero;
                        break;

                    //允许最大化按钮
                    case 0xf020:
                        //m.WParam = IntPtr.Zero;
                        break;

                    //允许最小化按钮
                    case 0xf030:
                        //m.WParam = IntPtr.Zero;
                        break;

                    //禁用还原按钮
                    case 0xf120:
                        //m.WParam = IntPtr.Zero;
                        break;

                    default:
                        //m.WParam = IntPtr.Zero;
                        break;
                }
            }
            base.WndProc(ref m);
        }

        /// <summary>
        /// 当前时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NowTimer_Tick(object sender, EventArgs e)
        {
            TimeLabel.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>设备列表
        /// 
        /// </summary>
        public void loadDeviceList()
        {
            List<Device> list = SqlSugarHelper.Inquireable<Device>(null);

            foreach (Device item in list)
            {
                Log.Debug("开始联接端口" + item.port);
                string deviceNumber = item.number.ToString();
                string portName = item.port; // 串口地址
                int baudRate = item.baudRate;   // 波特率
                var dataBits = 8;      // 数据位
                var stopBits = StopBits.One; // 停止位
                var parity = Parity.None;    // 校验位
                SerialPort serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
                if (!serialPortDic.ContainsKey(item.port))
                {
                    try
                    {
                        serialPort.Open();
                        if (serialPort.IsOpen)
                        {
                            Log.Info(portName + "：端口连接成功");
                            deviceSerialPortDic[item.number.ToString()] = serialPort;
                            serialPortDic[item.port] = serialPort;
                        }
                        else
                        {
                            Log.Info(portName + "：端口连接失败");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(portName + "连接异常：" + ex.Message);
                    }
                }
                else
                {
                    deviceSerialPortDic[deviceNumber] = serialPortDic[item.port];
                    Log.Info(portName + "端口连接成功");
                }
            }

            Task.Run(() =>
            {
                loadDevicePointList();
            });
        }
       
        /// <summary>设备点位列表
        /// 
        /// </summary>
        public void loadDevicePointList()
        {
            List<DevicePoint> list = SqlSugarHelper.Inquireable<DevicePoint>(null);
            foreach (DevicePoint item in list)
            {
                if (deviceSerialPortDic.ContainsKey(item.device_number.ToString()))
                {
                    Dictionary<string, Object> obj = new Dictionary<string, Object> { };
                    obj["slaveAddress"] = item.device_number;
                    obj["startAddress"] = item.address;
                    obj["numberOfPoints"] = 1;
                    obj["rangeMin"] = item.rangeMin;
                    obj["rangeMax"] = item.rangeMax;
                    obj["signalMin"] = item.outMin;
                    obj["signalMax"] = item.outMax;
                    SerialPort serialPort = deviceSerialPortDic[item.device_number.ToString()];
                    ModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
                    master.Transport.WriteTimeout = 1000;
                    master.Transport.ReadTimeout = 1000;
                    obj["master"] = master;
                    obj["serialPort"] = serialPort;
                    obj["deviceAddress"] = item.address;
                    masterDic[item.point_number.ToString()] = obj;
                }
                else
                {
                    string log = string.Format("【{0}】连接异常,无法读取【{1}】", item.device_name, item.point_name);
                    Log.Error(log);
                }
            }

            Task.Run(() =>
            {
                loadFormPointList();
            });
        }

        /// <summary>界面点位列表
        /// 
        /// </summary>
        public void loadFormPointList()
        {
            List<FormPoint> list = SqlSugarHelper.Inquireable<FormPoint>(null);
            foreach (FormPoint item in list)
            {
                frormPointDic[item.name] = item.device_point_number.ToString();
            }
            this.HideWaitForm();
            Task.Run(() =>
            {
                SetupVoice();
            });

        }

        /// <summary>设置语音
        /// 
        /// </summary>
        private void SetupVoice()
        {
            string key = "voice";

            if (frormPointDic.ContainsKey(key))
            {
                string pointNumber = frormPointDic[key];
                if (masterDic.ContainsKey(pointNumber))
                {
                    Dictionary<string, object> dic = masterDic[pointNumber];
                    voiceSerialPort = (SerialPort)dic["serialPort"];
                    voiceDeviceAddress = dic["deviceAddress"].ToString();
                    int address = voiceDeviceAddress.ToInt();
                    voiceDeviceAddress = address.ToString("00");
                    voiceSerialPort.DataReceived += new SerialDataReceivedEventHandler(receivedData);//接收数据事件
                    voiceSerialPort.ReadTimeout = 3;
                    try
                    {
                        Byte[] strbyte = Tool.HexStringToBytes("CCDDAA");
                        voiceSerialPort.Write(strbyte, 0, strbyte.Length);//发送数据
                    }
                    catch (Exception ex)
                    {
                        Log.Error("语音模块联接指令下发异常：" + ex.Message);
                    }
                }
                else
                {
                    Log.Debug("语音master未创建");
                }
            }
        }

        /// <summary>收到串口回复
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void receivedData(object sender, SerialDataReceivedEventArgs e)//接收数据
        {
            SerialPort serialPort = (SerialPort)sender;

            int len = serialPort.BytesToRead;//获取可以读取的字节数

            byte[] buff = new byte[len];//创建缓存数据数组

            try
            {
                serialPort.Read(buff, 0, len);//把数据读取到buff数组

                Invoke((new Action(() =>
                {
                    string back = BitConverter.ToString(buff, 0, buff.Length).Replace("-", "");
                    if (back.Contains("CCDDAA"))
                    {
                        Log.Info("语音模块已联接");
                        voiceBroadcastState = true;
                        if (voiceBroadcastState)
                        {
                            Broadcast("开机，请建立工程");
                        }
                    }
                })));
            }
            catch (Exception ex)
            {
                Log.Error("读取串口回复数据异常：" + ex.Message);
            }
        }

        /// <summary>播报
        /// 
        /// </summary>
        /// <param name="msg"></param>
        private void Broadcast(string content)
        {
            Log.Debug("语音播报：" + content);
            
            string lengthString = Tool.StringByteLength(content).ToString("X");
            if (lengthString.Length < 2)
            {
                lengthString = "0" + lengthString;
            }
            Log.Info(string.Format("数据长度:{0}", lengthString));
            string hexContent = Tool.GetHexFromChs(content);
            Log.Info(string.Format("数据内容:{0}", hexContent));

            string command = voiceDeviceAddress + "1000000000" + lengthString + hexContent;
            Log.Info(string.Format("指令:{0}", command));

            string crc = Tool.CRCForModbus(command);
            command = command + crc;
            if (voiceSerialPort != null)
            {
                if (voiceSerialPort.IsOpen)
                {
                    Byte[] strbyte = Tool.HexStringToBytes(command);
                    voiceSerialPort.Write(strbyte, 0, strbyte.Length);//发送数据
                    Log.Info(string.Format("下发播报指令：{0}", command));
                }
                else
                {
                    Log.Info("联接错误，无法下发播报指令");
                }
            }
        }

        public Index()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.Manual;
            Screen primaryScreen = Screen.PrimaryScreen;
            this.MaximizedBounds = primaryScreen.WorkingArea;
            this.MinimumSize = primaryScreen.WorkingArea.Size;
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            NowTimer_Tick(this.NowTimer, null);
            this.NowTimer.Enabled = true;
        }

        private void Main_Load(object sender, EventArgs e)
        {
            this.ShowWaitForm("加载点位");
            Task.Run(() =>
            {
                loadDeviceList();
            });
        }

        /// <summary>设备管理
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeviceButton_Click(object sender, EventArgs e)
        {
            DeviceManageForm frm = new DeviceManageForm();
            frm.ShowDialog();
        }

        /// <summary>试压模板
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TemplateButton_Click(object sender, EventArgs e)
        {
            ManageTemplateForm frm = new ManageTemplateForm();
            frm.ShowDialog();
        }

        /// <summary>系统设置
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetButton_Click(object sender, EventArgs e)
        {
            Log.Debug("开始联接端口");
            string deviceNumber = "12";
            string portName = "COM4"; // 串口地址
            int baudRate = 9600;   // 波特率
            var dataBits = 8;      // 数据位
            var stopBits = StopBits.One; // 停止位
            var parity = Parity.None;    // 校验位
            SerialPort serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            try
            {
                serialPort.Open();
                if (serialPort.IsOpen)
                {
                    Log.Info(portName + "：端口连接成功");
                    
                }
                else
                {
                    Log.Info(portName + "：端口连接失败");
                }
            }
            catch (Exception ex)
            {
                Log.Error(portName + "连接异常：" + ex.Message);
            }
        }

        /// <summary>数据库设置
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DatabaseButton_Click(object sender, EventArgs e)
        {
            SetDBForm frm = new SetDBForm();
            frm.ShowDialog();
        }
        
        /// <summary>界面管理
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormButton_Click(object sender, EventArgs e)
        {
            ManageFormPoint frm = new ManageFormPoint();
            frm.ShowDialog();
        }

        private void AddProjectButton_Click(object sender, EventArgs e)
        {
            AddProjectForm frm = new AddProjectForm();
            frm.ShowDialog();
        }
    }
}
